package com.example.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.publice.annotation.HideField;

/**
 * 对象帮助类
 * 
 * @author wangkai
 *
 * @date: 2019年6月18日 上午11:42:10
 */
public class EntityUtil {

	/**
	 * 隐藏对象属性
	 * 
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	public static Map<Object, Object> formateEntityMap(Object entity) {
		Map<Object, Object> result = new HashMap<>();
		try {
			Class<?> cl = entity.getClass();
			Field[] fields = getAllFields(entity);
			for (Field field : fields) {
				if (!"serialVersionUID".equals(field.getName())) {
					HideField ann = field.getAnnotation(HideField.class);
					if (ann == null || ann.hide() != 1) {
						PropertyDescriptor pd = new PropertyDescriptor(field.getName(), cl);
						Method rM = pd.getReadMethod();
						result.put(field.getName(), rM.invoke(entity));
					}
				}
			}
		} catch (Exception e) {
			System.err.println(e);
		}
		return result;
	}

	/**
	 * 隐藏对象属性
	 * 
	 * @param entity
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T formateEntity(Object entity) {
		try {
			return (T) mapToObject(formateEntityMap(entity), entity.getClass());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * map转对象
	 * 
	 * @param map
	 * @param beanClass
	 * @return
	 * @throws Exception
	 */
	public static <T> T mapToObject(Map<Object, Object> map, Class<T> beanClass) throws Exception {
		if (map == null)
			return null;
		T obj = beanClass.newInstance();
		Field[] fields = obj.getClass().getDeclaredFields();
		for (Field field : fields) {
			int mod = field.getModifiers();
			if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
				continue;
			}
			field.setAccessible(true);
			field.set(obj, map.get(field.getName()));
		}
		return obj;
	}

	/**
	 * 对象转map
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public static Map<Object, Object> objectToMap(Object obj) throws Exception {
		if (obj == null) {
			return null;
		}
		Map<Object, Object> map = new HashMap<Object, Object>();
		Field[] declaredFields = obj.getClass().getDeclaredFields();
		for (Field field : declaredFields) {
			field.setAccessible(true);
			map.put(field.getName(), field.get(obj));
		}
		return map;
	}

	private static Field[] getAllFields(Object object) {
		Class<?> clazz = object.getClass();
		List<Field> fieldList = new ArrayList<>();
		while (clazz != null) {
			fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
			clazz = clazz.getSuperclass();
		}
		Field[] fields = new Field[fieldList.size()];
		fieldList.toArray(fields);
		return fields;
	}

}
